package com.atguigu.tingshu.common.aspect;


import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.annotation.GuiGuLogin;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.handler.GlobalExceptionHandler;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Component
@Aspect
@Slf4j
public class GuiGuLoginAspect {
    @Autowired
    RedisTemplate<String,String> redisTemplate;


    @Around(value = "@annotation(guiGuLogin)")
    public Object loginAspect(ProceedingJoinPoint joinPoint, GuiGuLogin guiGuLogin){

        //获取请求头中的token
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes =(ServletRequestAttributes)requestAttributes;
        String token = servletRequestAttributes.getRequest().getHeader("token");

        //判断是否需要登录
        boolean required = guiGuLogin.required();
        if (required){
            //判断token是否为空
            if (StringUtils.isEmpty(token)){
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }
            //token不为空,跟据token获取用户信息
            String s = redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
            UserInfo userInfo = JSON.parseObject(s, UserInfo.class);
            //判断用户信息是否为空
            if (userInfo == null){
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }

            //存在用户信息就将用户信息存储到threadLocal中
            AuthContextHolder.setUserId(userInfo.getId());
            AuthContextHolder.setUsername(userInfo.getNickname());
        }else {
            //不需要登录，非保护接口
            //判断token是否为空
            if (!StringUtils.isEmpty(token)){
                //token不为空,跟据token获取用户信息
                String s = redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
                UserInfo userInfo = JSON.parseObject(s, UserInfo.class);
                //判断用户信息是否为空
                if (userInfo != null){
                    //存在用户信息就将用户信息存储到threadLocal中
                    AuthContextHolder.setUserId(userInfo.getId());
                    AuthContextHolder.setUsername(userInfo.getNickname());
                    }
            }
        }

        //执行后续目标方法并返回
        try {
            Object proceed = joinPoint.proceed();
            return proceed;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }finally {
            AuthContextHolder.removeUserId();
            AuthContextHolder.removeUsername();
        }



    }
}
